package validation

import (
	"gitee.com/enzolwb/my-web-scaffold/pkg/app"
	"gitee.com/enzolwb/my-web-scaffold/pkg/ecode"
	"gitee.com/enzolwb/my-web-scaffold/pkg/setting"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"github.com/go-playground/locales/en"
	"github.com/go-playground/locales/zh"
	ut "github.com/go-playground/universal-translator"
	"github.com/go-playground/validator/v10"
	enTranslation "github.com/go-playground/validator/v10/translations/en"
	zhTranslation "github.com/go-playground/validator/v10/translations/zh"
	"github.com/pkg/errors"
	"reflect"
)

var trans ut.Translator

func SetUp() error {
	lang := setting.AppSetting.Lang
	v := binding.Validator.Engine().(*validator.Validate)
	switch lang {
	case "zh":
		trans, _ = ut.New(zh.New()).GetTranslator(lang)

		if err := zhTranslation.RegisterDefaultTranslations(v, trans); err != nil {
			return err
		}
		v.RegisterTagNameFunc(func(fld reflect.StructField) string {
			return fld.Tag.Get("comment")
		})
		break

	case "en":
		trans, _ = ut.New(en.New()).GetTranslator(lang)
		if err := enTranslation.RegisterDefaultTranslations(v, trans); err != nil {
			return err
		}
		v.RegisterTagNameFunc(func(fld reflect.StructField) string {
			return fld.Tag.Get("en_comment")
		})
		break

	default:
		return errors.New("configure:lang not match")
	}

	//自定义验证方法
	v.RegisterValidation("is-validuser", validUser)
	v.RegisterValidation("bookabledate", bookableDate)

	return nil

}

func Error(err error) (message string) {
	if validationErrors, ok := err.(validator.ValidationErrors); !ok {
		return err.Error()
	} else {
		for _, e := range validationErrors {
			message += e.Translate(trans) + ";"
		}
	}
	return message
}

// BindValidParams bind and validated data.
func BindValidParams(c *gin.Context, input interface{}) error {
	//接收GET POST请求参数 如果只想接收GET 使用ShouldBindQuery ,只想接收POST ShouldBindJson.
	if err := c.ShouldBind(input); err != nil {
		//验证失败 直接返回json了
		app.Response(c, ecode.ErrRequest.Reload(Error(err)))
		return errors.New(Error(err))
	}
	return nil
}
